#include <QFileDialog>
#include <QMessageBox>
#include <QImage>

#include "opencv2/opencv.hpp"

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "comm_impl.h"
#include "BleDevice.h"
#include "ufw_protocol.h"

#include "cfdl_ptl_impl.h"
#include "cfdl_login.h"

using namespace cv;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->transBar->setAlignment(Qt::AlignCenter);

    ui->opencvBox->addItem(u8"高斯模糊");
    ui->opencvBox->addItem(u8"中值滤波");

    bleCtrl = new BleDevice(this);

    connect(UsrCommImpl::Instance(), &UsrCommImpl::CommSignalLog, this, [this](const QString& log){
        ui->logTextEdit->appendPlainText(log);
        if (ui->logTextEdit->blockCount() > 150000)
            ui->logTextEdit->clear();
    });

    connect(bleCtrl, &BleDevice::signalBleInfo, this, [this](const QString& name, const QString& addr){
        Q_UNUSED(addr);
        ui->bleDevComboBox->addItem(name);
    });

    connect(bleCtrl, &BleDevice::bleStatus, this, &MainWindow::slot_ble_state_business);

    connect(bleCtrl, &BleDevice::SignalUpdateProgress,
            this, &MainWindow::SlotUpdateProgress);

    connect(cfdl_login::Instance(), &cfdl_login::signalDevLogin, this, &MainWindow::slot_cfdl_dev_login);
}

MainWindow::~MainWindow()
{
    delete ui;
    //delete bleCtrl; //not needed
}

void MainWindow::SlotUpdateProgress(int index)
{
    ui->transBar->setValue(index);
}

void MainWindow::on_bleSearchBtn_clicked()
{
    if(bleCtrl->isBleConnect()) return;

    if(bleCtrl->isBleSearch()) {
        ui->bleSearchBtn->setText(QStringLiteral("搜索蓝牙"));
        bleCtrl->bleSearchStop();
    }
    else {
        ui->bleSearchBtn->setText(QStringLiteral("停止搜索"));
        bleCtrl->bleSearchStart();
        ui->bleDevComboBox->clear();
    }
}


void MainWindow::on_bleOpBtn_clicked()
{
    if(bleCtrl->isBleSearch()) return;

    if(bleCtrl->isBleConnect()) {
        ui->bleOpBtn->setText(QStringLiteral("连接蓝牙"));
        bleCtrl->bleDisconnet();
    }
    else {
        QString name = ui->bleDevComboBox->currentText();
        if(!name.isEmpty()) {
            bleCtrl->bleConnect(name);
            ui->bleOpBtn->setText(QStringLiteral("断开连接"));
        }
    }
}


void MainWindow::on_clrLogBtn_clicked()
{
    ui->logTextEdit->clear();
}

void MainWindow::slot_cfdl_dev_login(uint8_t vid, uint16_t pid, uint8_t chid)
{
    ui->cfdlDevBox->addItem(QString::number(pid, 16));
}

void MainWindow::slot_ble_state_business(quint16 state)
{
    switch(state) {
    case BLESearchStop:
        ui->bleSearchBtn->setText(QStringLiteral("搜索蓝牙"));
        break;

    case BLEDisconnect:
        ui->bleOpBtn->setText(QStringLiteral("连接蓝牙"));
        ui->transBar->setValue(0);
        ui->fileBtn->setEnabled(true);

        ui->updateBtn->setText(u8"开始传输");
        m_UpdateIsRun = false;
        break;

    case BLETransFailed:
        ui->transBar->setValue(0);
    case BLETransEnd:
        ui->updateBtn->setText(u8"开始传输");
        ui->fileBtn->setEnabled(true);
        m_UpdateIsRun = false;
        {
            QString tmp = QString("[%1]:trans file end").arg(MyDATETIMEMS);
            ui->logTextEdit->appendPlainText(tmp);
        }
        break;
    }
}

void MainWindow::on_fileBtn_clicked()
{
    QString path = QFileDialog::getOpenFileName(nullptr,
                                                u8"文件",
                                                "/",
                                                "picture File(*.bmp *.SPG *.png *.ufw)");
    if(path.isEmpty()) return;

    ui->fileNameEdit->setText(path);
}


void MainWindow::on_updateBtn_clicked()
{
    QString path = ui->fileNameEdit->text();
    if(path.isEmpty() || !bleCtrl->isBleConnect()) return;

    if(!m_UpdateIsRun) {
        QFile file(path);
        if(file.open(QIODevice::ReadOnly)) {
            QDataStream out(&file);

            QByteArray totalFile;
            char tmpBuf[1024];
            while(!out.atEnd())
            {
                int sz = out.readRawData(tmpBuf, 1024);
                QByteArray block(tmpBuf, sz);
                totalFile += block;
            }

            int fileLen = totalFile.length() + 32;
            qDebug() << "read fireware length " << fileLen;
            QFileInfo fileinfo = QFileInfo(path);

            if(fileLen > 100) {
                QString tmp = ui->payloadEdit->text();
                quint16 segment = tmp.toUShort();
                if(segment > (JL_PTL_MSG_LEN - 36) || segment < 64) {
                    segment = JL_PTL_MSG_LEN - 40;
                }

                int updateLen = fileLen / segment + ((fileLen % segment) > 0);

                ui->transBar->setRange(0, updateLen);
                ui->fileBtn->setEnabled(false);

                m_UpdateIsRun = true;
                ui->updateBtn->setText(u8"停止传输");

                tmp = QString("[%1]:start trans picture,file_size:%2,slice_size:%3,slice_total:%4")
                    .arg(MyDATETIMEMS).arg(fileLen).arg(segment).arg(updateLen);
                ui->logTextEdit->appendPlainText(tmp);

                bleCtrl->updateFirmware(totalFile, segment, fileinfo.suffix());
            }
            else {
                QMessageBox::information(nullptr, "warning", u8"固件长度范围(0.1~8MByte)");
            }
        }
    }
    else {
        ui->transBar->setValue(0);
        ui->fileBtn->setEnabled(true);

        ui->updateBtn->setText(u8"开始传输");
        m_UpdateIsRun = false;
    }
}


void MainWindow::on_imgFileBtn_clicked()
{
    imgPath = QFileDialog::getOpenFileName(nullptr,
                                                u8"图片",
                                                "/",
                                                "picture File(*.bmp *.jpg *.jpeg *.png)");
    if(imgPath.isEmpty()) return;

    ui->imgEdit->setText(imgPath);

    Mat img = imread(imgPath.toStdString().c_str());
    if(img.empty()) {
        imgPath.clear();
        ui->imgEdit->clear();
        return;
    }

    //Mat转QImage 颜色
    cvtColor(img, img, ColorConversionCodes::COLOR_BGR2RGB);
    //Mat转QImage 像素
    QImage source_img = QImage(img.data,img.cols,img.rows,img.cols*img.channels(),QImage::Format_RGB888);
    source_img = source_img.scaled(360, 360, Qt::KeepAspectRatio);
    ui->img1Label->setPixmap(QPixmap::fromImage(source_img));
}

void MainWindow::on_opencvBtn_clicked()
{
    if(imgPath.isEmpty()) return;

    Mat img = imread(imgPath.toStdString().c_str());
    Mat retimage;

    switch(ui->opencvBox->currentIndex())
    {
    case 0:
        //高斯模糊
        GaussianBlur(img,retimage,Size(5,5),0,0);
        break;
    case 1:
        //中值滤波
        medianBlur(img,retimage,3);
        break;
    }


    //Mat转QImage 颜色
    cvtColor(retimage, retimage, ColorConversionCodes::COLOR_BGR2RGB);
    //Mat转QImage 像素
    QImage source_img = QImage(retimage.data,retimage.cols,retimage.rows,retimage.cols*retimage.channels(),QImage::Format_RGB888);
    source_img = source_img.scaled(360, 360, Qt::KeepAspectRatio);
    ui->img2Label->setPixmap(QPixmap::fromImage(source_img));


}

